Lua 笔记

语法简介

词法约定

变量是以字母或下划线开头的字母下划线数字序列,不要使用下划线加大写字母的标识符,因为Lua的保留字是这种形式
Lua的保留字:

and break do else elseif
end false for function if
in local nil not or
repeat return then true until
while

在Lua中大小写敏感,如and是保留字,And和AND则不是保留字

代码规范

Lua 的多条语句之间并不要求任何分隔符, 如 C 语言的分号(;), 其中换行符也同样不能起到语句分隔的
作用

Lua的注释有两种:单行注释,使用两个减号(–)开头就行了

1
--单行注释

多行注释,两个减号(–)后面紧跟两个正中括弧([[),后面就是注释语句,结束时减减(–)紧跟两个反中括弧(]])

1
2
3
4
5
--[[我是
跨行注
释语
--]]

变量

Lua中分全局变量和局部变量。
默认创建的就是全局变量,访问一个没有初始化的全局变量是不会出错的,只不过结果是 nil ,这就相当于 null,想要删除一个全局变量时,将其赋值为nil就行了。
局部变量要通过 local 进行声明,局部变量只在声明的代码块中有效

1
2
3
4
5
local m = 9
if m<=10 then
local m = 5
print(m)
end

如上代码中m为5

Lua是动态类型语言,声明时不要类型定义,赋值什么类型变量就是什么类型。使用 type() 函数可以获取变量的类型信息。

变量的类型

Lua有 nil、 boolean、 number、 string、 userdata、 function、 thread 和 table共计8种变量类型。

  1. nil型只有一个值,就是nil,用于表示无效值。
  2. boolean 有false和true两种值。Lua中所有的值都可以作为条件,只有 false和nil 视为假,其余的均视为真,如数字0和空字符串。
  3. number就是实数
  4. string 就是字符串,lua的string可以包含任何数值字符,包括嵌入的0。例:

    1
    2
    3
    m ="\97\98\99"
    print(m) ----->abc
    print("\09798")----->a98

和Java一样的是Lua的字符串也是恒定不变的。

  1. table是lua中的唯一数据结构,可以用于实现数组,矩阵,链表,队列等其他数据结构。

    1
    2
    3
    4
    5
    6
    local t = {32,"jeep", name = "cherry"}
    local p = {["name"] = "peach"}
    print(t[1]) --> 32
    print(t[2]) --> jeep
    print(t["name"],t.name) --> cherry cherry
    print(p["name"],p.name) --> peach peach

需要注意的是 table的索引是从1开始的 如果取其为零的索引会得到 nil 。table 没有固定大小 ,可以动态添加元素到table中。获取table的长度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
t = {10,5,797}
table.getn(t)
或者
#t
在Lua5.3版本getn()失效了,要自己构建一个
function table.getn(x)
local ret = 0 ---->Lua中变量默认nil值,使用nil值进行计算会出差,所以记得初始化变量
for i in pairs(x) do
ret=ret+1
end
return ret
end

表除了保存数据外,还可以保存算式,保存算式时算式是不算在表的长度中的:

1
2
local t = {1, a = 8, 3}
print(#t) -->结果为2

有点类似于类中的成员变量一样,调用算式时:

1
2
local t = {1, a = 8, 3}
print(t.a) -->结果为8

此外需要注意 不要在表中保存nil 会造成表的长度返回不准

  1. function,函数是第一类值, 意味着函数可以存储在变量中, 可以作为函数的参数, 也可以作为函数的返回值。 这个特性给了语言很大的灵活性(第一类值:就是函数function与int double地位一样,可以作为对象传递,可以作为函数的返回值)
    Lua中使用函数时记得先定义函数再使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function table.getn(x)
    local ret=0
    for i in pairs(x) do
    ret=ret+1
    end
    return ret
    end
    local xiang = {10,22,34,42,51}
    print("xiang length ==",table.getn(xiang))
  2. userdata用来描述应用程序或者使用c实现的库创建的新类型,userdata只实现了赋值和相等操作。

  3. thread,在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
    线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

表达式

  1. 算数操作符,+ - * / ^(指数) %(取模)
    其中 - 可用于加减运算,也可用于表示负数。另外需要注意的是 Lua 没有自增(++)和自减(–)运算符
  2. 关系操作符,>、 <、 >=、 <=、 ==、 ~=
    == ~= 用于比较相等和不相等。如果两个值的类型不同,那么在Lua中他们就是不等的,nil与自己相等。tables,userdata,functions是通过引用比较,只有当他们引用同一个对象时才相等。

    1
    2
    3
    4
    5
    6
    a = {x=1,y=2}
    b = {x=1,y=2}
    c = a
    print(a==c) --> true
    print(b==c) --> false

Lua比较数字时按数字大小进行,比较字符串按字母顺序进行,字符串或数字与不同类型的值比较时会报错。

  1. and or not 和与非,在boolean值的逻辑运算时是一样的,但是不同于C,JAVA的地方在于,进行数值的逻辑运算时Lua是不会报错的。

    1
    2
    3
    4
    5
    6
    7
    print(4 and 5) --> 5
    print(nil and 13) --> nil
    print(false and 13) --> false
    print(4 or 5) --> 4
    print(false or 5) --> 5
    print(true and false) --> false
    print(true or false) --> true

如上,使用 and 时,如果是两个数的运算,结果总是较大的那个数,使用 or 时,结果总是较小的那个数。如果是数字和boolean或者nil的运算,那么可以按照以下优先级:

1
or 小数字---大数字---true---false---nil and

进行or运算时,结果优先取上式左边的值,进行and运算时,优先取右边的值。

  1. 字符串连接,字符串连接使用 .. 进行操作,如果有数字,就会将数字转换为字符串

    1
    2
    3
    4
    print (“hello” .. “everyone”) --> hello everyone
    print ( 2 .. “ apples”) --> 2 apples
    s = 2 .. 3
    print(s , type(s)) --> 23 string
  2. 构造表,表使用 {} 进行构造,如:

    1
    2
    b = {x = 0, y = 1, "Monday", 109}
    print(b[1],b[2],b.x,b.y) --> Monday 109 0 1

函数

函数无非两个功能,一,完成特定的操作就像Java的void函数一样。二进行运算返回一个数值,也就是有返回值的函数。

  1. Lua 函数实参和形参的匹配与赋值语句类似, 多余部分被忽略, 缺少部分用 nil 补足

    1
    2
    3
    4
    5
    function f(a, b)
    return a and b
    end
    c = f(3) d = f(3,4) e= f(3,4,5)
    print(c, d, e) --> nil 4 4
  2. Lua 函数支持返回多个结果值

    1
    2
    3
    function foo0 () end -- returns no results
    function foo1 () return 'a' end -- returns 1 result
    function foo2 () return 'a','b' end -- returns 2 results

当调用作为表达式最后一个参数或者仅有一个参数时, 根据变量个数函数尽可能多地返回多个值, 不
足补 nil, 超出舍去。

1
2
3
4
5
6
x,y = foo2() -- x='a', y='b'
x = foo2() -- x='a', 'b' is discarded
x,y,z = 10,foo2() -- x=10, y='a', z='b'
x,y = foo0() -- x=nil, y=nil
x,y = foo1() -- x='a', y=nil
x,y,z = foo2() -- x='a', y='b', z=nil

其他情况下, 函数调用仅返回第一个值(如果没有返回值为 nil)

1
2
3
4
5
x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded
print(foo2(), 1) --> a 1
print(foo2() .. "x") --> ax
a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4

与Java相同Lua也支持可变参数,同样使用 三个点表示可变参数。Lua 将函数的可变参数放在一个叫 arg 的表中, 除了参数以外, arg 表中还有一个域 n 表示参数的个数。在函数参数中, 固定参数和可变参数可以一起声明, 但是固定参数一定要在变长参数之前声明。

1
2
3
function test(arg1,arg2,...)
...
end

基本语法

  1. 赋值语句
    Lua 中的赋值语句和其它编程语言基本相同, 唯一的差别是 Lua 支持“多重赋值”。如:

    1
    local x,y = "test", 12 -- “test” 赋值给 x, 12 赋值给 y
  2. 局部变量和块
    可以用 local 来定义局部变量, 例如:

    1
    local a = "china"

local 是保留字, 表示该变量是局部变量。 和全局变量不同的是, 局部变量的作用范围仅限于其所在的程
序块。 Lua 中的程序可以为控制结构的执行体、 函数执行体或者是一个程序块。

1
2
3
4
5
local x =12
if x >10 then
local x = 0
print(“x=”,x) -- 打印结果是: x= 0 , 而不是 12
end
  1. 控制语句
    if 语句,if 语句有 3 种结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    if 条件语句 then
    执行语句
    end
    if 条件语句 then
    执行语句
    else
    执行语句
    end
    if 条件语句1 then
    执行语句
    elseif 条件语句2 then
    执行语句
    … -- 很多个 elseif
    执行语句
    end

while语句,while 语句语法如下:

1
2
3
while 条件语句 do
执行语句
end

repeat语句 repeat 语句语法如下:

1
2
3
repeat
statements
until condition

repeat和C中的do while语句一样

break 和 continue,break 跳出内层循环, continue 不会跳出循环, 但会结束本次判断。